package com.qboot.quartz.service.impl;

import com.qboot.common.entity.Result;
import com.qboot.common.exception.QuartzException;
import com.qboot.common.utils.AssertUtils;
import com.qboot.quartz.service.QuartzService;
import lombok.RequiredArgsConstructor;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Map;

/**
 * Quartz 接口实现类
 *
 * @author Tellsea
 * @date 2023/2/14
 */
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class QuartzServiceImpl implements QuartzService {

    private final Scheduler scheduler;

    /**
     * 增加一个job
     *
     * @param jobClass     任务实现类
     * @param jobName      任务名称(建议唯一)
     * @param jobGroupName 任务组名
     * @param jobTime      时间表达式 （如：0/5 * * * * ? ）
     * @param jobData      参数
     */
    @Override
    public Result addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobTime, Map jobData) {
        try {
            // 创建jobDetail实例，绑定Job实现类
            // 指明job的名称，所在组的名称，以及绑定job类
            // 任务名称和组构成任务key
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
                    .build();
            // 设置job参数
            if (!ObjectUtils.isEmpty(jobData)) {
                jobDetail.getJobDataMap().putAll(jobData);
            }
            // 定义调度触发规则
            // 使用cornTrigger规则
            // 触发器key
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobTime))
                    .startNow()
                    .build();
            // 把作业和触发器注册到任务调度中
            scheduler.scheduleJob(jobDetail, trigger);
            return Result.ok("添加成功");
        } catch (Exception e) {
            throw new QuartzException("添加失败：" + e.getMessage());
        }
    }

    /**
     * 更新 一个job的 时间表达式
     *
     * @param jobName
     * @param jobGroupName
     * @param jobTime
     */
    @Override
    public Result updateJob(String jobName, String jobGroupName, String jobTime) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            AssertUtils.isTrue(ObjectUtils.isEmpty(trigger), "任务不存在");
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build();
            // 重启触发器
            scheduler.rescheduleJob(triggerKey, trigger);
            return Result.ok("更新成功");
        } catch (SchedulerException e) {
            e.printStackTrace();
            throw new QuartzException("更新失败：" + e.getMessage());
        }
    }

    /**
     * 删除任务一个job
     *
     * @param jobName      任务名称
     * @param jobGroupName 任务组名
     */
    @Override
    public Result deleteJob(String jobName, String jobGroupName) {
        try {
            scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
            return Result.ok("删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            throw new QuartzException("删除失败：" + e.getMessage());
        }
    }

    /**
     * 暂停一个job
     *
     * @param jobName
     * @param jobGroupName
     * @return
     */
    @Override
    public Result pauseJob(String jobName, String jobGroupName) {
        try {
            scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));
            return Result.ok("暂停成功");
        } catch (SchedulerException e) {
            e.printStackTrace();
            throw new QuartzException("暂停失败：" + e.getMessage());
        }
    }

    /**
     * 恢复一个job
     *
     * @param jobName
     * @param jobGroupName
     */
    @Override
    public Result resumeJob(String jobName, String jobGroupName) {
        try {
            scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName));
            return Result.ok("恢复成功");
        } catch (SchedulerException e) {
            e.printStackTrace();
            throw new QuartzException("恢复失败：" + e.getMessage());
        }
    }

    /**
     * 立即执行一个job
     *
     * @param jobName
     * @param jobGroupName
     */
    @Override
    public Result runJobNow(String jobName, String jobGroupName) {
        try {
            scheduler.triggerJob(JobKey.jobKey(jobName, jobGroupName));
            return Result.ok("执行成功");
        } catch (SchedulerException e) {
            e.printStackTrace();
            throw new QuartzException("执行失败：" + e.getMessage());
        }
    }
}
